﻿using System.Collections.Generic;
using System.Linq;

namespace VPLink2014.Data.MesApplis
{
	public class VODepartementMapper : VOTeamMapper
	{
		public VODepartement departement;
		public VODepartementMapper()
			: base()
		{
		}
		public VODepartementMapper( string name )
			: base()
		{
			using( VPLinkLogConnection db = new VPLinkLogConnection() )
			{
				departement = ( from u in db.VplinkEntities.Departements
								where u.nom == name
								select new VODepartement() { Name = u.nom, Id = u.id } ).FirstOrDefault();
			}
		}

		public override void SetApplications( List<VOApplication> applications )
		{
			using( VPLinkLogConnection db = new VPLinkLogConnection() )
			{
				Departement departementDb = ( from Departement dept in db.VplinkEntities.Departements
											   where dept.id == departement.Id
											   select dept ).FirstOrDefault<Departement>();

				// Deleted Apps
				List<AppliDept> deletedApps = departementDb.AppliDepts.Where( i => !applications.Select( x => x.Id ).Contains( i.appli ) ).ToList<AppliDept>();
                deletedApps.ForEach(x => db.VplinkEntities.AppliDepts.Remove(x));

				//Delete from users Db
				List<User> usersWithApplisFromServiceDb = ( from User usr in db.VplinkEntities.Users
															 from AppliUser appliUser in db.VplinkEntities.AppliUsers
															 where usr.Departement == this.departement.Name
															 where usr.Service == ""
															 where usr.LoginUser == appliUser.user
															 select usr ).Distinct().ToList<User>();
				foreach( User user in usersWithApplisFromServiceDb )
				{
					List<AppliUser> specificUserApps = user.AppliUsers
						.Where( i => !applications.Select( x => x.Id ).Contains( i.appli ) )
						.OrderBy( x => x.rang ).ToList<AppliUser>();
					for( int i = 0; i < specificUserApps.Count(); i++ )
					{
						specificUserApps[i].rang = applications.Count() + i + 1;
					}
					if( deletedApps.Count() > 0 )
					{
						List<AppliUser> deletedUserApps = user.AppliUsers.Where( i => deletedApps.Select( x => x.appli ).Contains( i.appli ) ).ToList<AppliUser>();
                        deletedUserApps.ForEach(x => db.VplinkEntities.AppliUsers.Remove(x));
					}
				}

				foreach( VOApplication application in applications )
				{
					Application appliDb = ( from Application appli in db.VplinkEntities.Applications
											 where appli.id == application.Id
											 select appli ).FirstOrDefault<Application>();

					UpdateUsers( db, usersWithApplisFromServiceDb, application, appliDb );

					UpdateTeamApplis( db, departementDb, application, appliDb );
				}
			}
		}

		private void UpdateTeamApplis( VPLinkLogConnection db, Departement departementDb, VOApplication application, Application appliDb )
		{
			AppliDept appliDepts = ( from AppliDept depts in db.VplinkEntities.AppliDepts
									 where depts.departement == departement.Id
									 where depts.appli == application.Id
									 select depts ).FirstOrDefault<AppliDept>();
			// Add New
			if( appliDepts == null )
			{
				AppliDept newAppliDept = new AppliDept()
				{
					Departement1 = departementDb,
					Application = appliDb,
					departement = this.departement.Id,
					appli = application.Id,
					rang = application.Rang,
					obligatoire = application.Obligatoire
				};
				db.VplinkEntities.AppliDepts.Add( newAppliDept );
			}
			else
			{
				// Update existing
				appliDepts.obligatoire = application.Obligatoire;
				appliDepts.rang = application.Rang;
			}
		}

		private static void UpdateUsers( VPLinkLogConnection db, List<User> usersWithApplisFromServiceDb, VOApplication application, Application appliDb )
		{
			foreach( User user in usersWithApplisFromServiceDb )
			{
				AppliUser appliUser = ( from AppliUser usrAppli in db.VplinkEntities.AppliUsers
										where usrAppli.appli == application.Id
										where usrAppli.user == user.LoginUser
										select usrAppli ).FirstOrDefault();

				if( appliUser == null )
				{
					db.VplinkEntities.AppliUsers.Add( new AppliUser()
					{
						appli = application.Id,
						user = user.LoginUser,
						User1 = user,
						Application = appliDb,
						obligatoire = application.Obligatoire,
						rang = application.Rang
					} );
				}
				else
				{
					appliUser.obligatoire = application.Obligatoire;
					appliUser.rang = application.Rang;
				}
			}
		}

		public override List<VOApplication> GetApplicationsTeam()
		{
			List<VOApplication> applicationsByDepartement = new List<VOApplication>();
			using( VPLinkLogConnection db = new VPLinkLogConnection() )
			{
				applicationsByDepartement = (
									from appliDept in db.VplinkEntities.AppliDepts
									from applis in db.VplinkEntities.Applications
									from depts in db.VplinkEntities.Departements
									where depts.nom == this.departement.Name
									where applis.id == appliDept.appli
									where depts.id == appliDept.departement
									orderby appliDept.rang
									select new VOApplication() { Id = applis.id, Url = applis.url, Name = applis.titre, Categorie = string.IsNullOrEmpty( applis.categorie ) ? "Autre" : applis.categorie, Description = applis.description, Obligatoire = appliDept.obligatoire, Rang = appliDept.rang } ).ToList<VOApplication>();
			}
			return applicationsByDepartement;
		}
	}
}
